﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Data;

namespace Helper
{
    /// <summary>
    /// Xml Helper
    /// </summary>
    public static class XmlHelper
    {
        /// <summary>
        /// get xml document for a object.
        /// </summary>
        /// <param name="obj">object</param>
        /// <returns>Xml Document</returns>
        public static XmlDocument ToXml(Object obj)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string xmlString = ToXmlString(obj);
            xmlDoc.LoadXml(xmlString);
            return xmlDoc;
        }

        /// <summary>
        /// get xml string for a object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>xml string</returns>
        public static String ToXmlString(Object obj)
        {
            using (StringWriter sw = new StringWriter())
            {
                Type t = obj.GetType();
                XmlSerializer xs = new XmlSerializer(t);

                xs.Serialize(sw, obj);

                return sw.ToString();
            }
        }

        /// <summary>
        /// get xml string for a table
        /// </summary>
        /// <param name="dt">data table</param>
        /// <param name="mode">xml write mode</param>
        /// <returns>xml string</returns>
        public static String ToXmlString(DataTable dt, XmlWriteMode mode)
        {
            if (dt != null)
            {
                using (StringWriter sw = new StringWriter())
                {
                    dt.WriteXml(sw, mode);
                    return sw.ToString();
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// get xml string for a table(Ignore Schema)
        /// </summary>
        /// <param name="dt">data table</param>
        /// <returns>xml string</returns>
        public static String ToXmlString(DataTable dt)
        {
            return ToXmlString(dt, XmlWriteMode.IgnoreSchema);
        }

        /// <summary>
        /// get a object from given xml string
        /// </summary>
        /// <typeparam name="T">type</typeparam>
        /// <param name="xmlString">xml string</param>
        /// <returns>a object that for a give type</returns>
        public static T ToObjectFromXml<T>(String xmlString)
        {
            XmlSerializer s = new XmlSerializer(typeof(T));
            using (StringReader reader = new StringReader(xmlString))
            {
                Object obj = s.Deserialize(reader);
                return (T)obj;
            }
        }

        /// <summary>
        /// set an attribute to a node, if attribute is not exist, then create it.
        /// </summary>
        /// <param name="node">Xml Node</param>
        /// <param name="attributeName">attribute name</param>
        /// <param name="attributeValue">attribute value</param>
        public static void SetNodeAttribute(XmlNode node, string attributeName, string attributeValue)
        {
            if (node == null || string.IsNullOrEmpty(attributeName))
            {
                return;
            }
            if (node.Attributes[attributeName] != null)
            {
                node.Attributes[attributeName].Value = attributeValue;
            }
            else
            {
                XmlAttribute attr = node.OwnerDocument.CreateAttribute(attributeName);
                attr.Value = attributeValue;
                node.Attributes.Append(attr);
            }
        }

        /// <summary>
        /// set an attribute to a node, if attribute is not exist, then create it.
        /// if the value is null or empty, then will remove attribute
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <param name="value"></param>
        public static void SetOrRemoveAttribute(XmlNode node, string attributeName, string value)
        {
            //if value is null or empty, then remove the attribute.
            if (string.IsNullOrEmpty(value))
            {
                if (node.Attributes[attributeName] != null)
                {
                    node.Attributes.Remove(node.Attributes[attributeName]);
                }
                return;
            }

            if (node.Attributes[attributeName] == null)
            {
                node.Attributes.Append(node.OwnerDocument.CreateAttribute(attributeName));
            }
            node.Attributes[attributeName].Value = value;
        }

        /// <summary>
        /// if value is true, set to '1', else remove the attribute.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <param name="value"></param>
        public static void SetAttribute(XmlNode node, string attributeName, bool value)
        {
            if (value)
            {
                SetOrRemoveAttribute(node, attributeName, "1");
            }
            else
            {
                SetOrRemoveAttribute(node, attributeName, "");
            }
        }

        /// <summary>
        /// get string attribute value
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static string GetStringValue(XmlNode node, string attributeName)
        {
            if (node.Attributes[attributeName] == null)
            {
                return string.Empty;
            }
            return node.Attributes[attributeName].Value;
        }

        /// <summary>
        /// get int attribute value
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static int GetIntValue(XmlNode node, string attributeName)
        {
            if (node.Attributes[attributeName] == null)
            {
                return 0;
            }
            int i = 0;
            int.TryParse(node.Attributes[attributeName].Value, out i);
            return i;
        }
        /// <summary>
        /// get bool attribute value
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static bool GetBoolValue(XmlNode node, string attributeName)
        {
            if (node.Attributes[attributeName] == null)
            {
                return false;
            }
            int i = 0;
            int.TryParse(node.Attributes[attributeName].Value, out i);
            return i == 1;
        }
        /// <summary>
        /// add child node to the node
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeName"></param>
        /// <param name="value"></param>
        public static void AddChildNode(XmlNode node, string nodeName, string value)
        {
            XmlNode newNode = node.OwnerDocument.CreateElement(nodeName);
            newNode.InnerText = value;
            node.AppendChild(newNode);
        }
    }
}
